﻿using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Threading;
using System.Threading.Tasks;

namespace Dwarf.Managed
{
    /// <summary>
    /// Solve the Sparse Linear Algebra problem with TPL parallelization  
    /// </summary>
    /// <remarks> 
    /// For the demonstration purposes of the project, 
    /// we have sparse matrix-vector multiplication.
    /// </remarks>
    class Solver
    {
        /// <summary>
        /// Number of rows in sparse matrix
        /// </summary>
        public int rowNum;
        /// <summary>
        /// Number of non-zero values in sparse matrix
        /// </summary>
        public int valNum;

        /// <summary>
        /// sparse matrix in Compressed Row Storage (CRS) format
        /// </summary>
        public double[] val;
        public int[] col_ind;
        public int[] row_ptr;

        /// <summary>
        /// Vector
        /// </summary>
        public double[] vector;
        /// <summary>
        /// Result vector
        /// </summary>
        public double[] result;

        /// <summary>
        /// Empty constructor.
        /// </summary>
        public Solver()
        {
        }

        /// <summary>
        /// TPL based method for sparse matrix-vector multiplication.
        /// </summary>
        public void Solve()
        {
            Parallel.For(0, rowNum, i =>                        //TPL directive Loop for number of rows in matrix
            {
                //The C# compler/runtime is not
                //hoisting the array addressing out of the loop
                //hence the following makes a big difference
                //result[i] = 0;
                double cell = 0.0;

                for (int j = row_ptr[i] - 1; j < row_ptr[i + 1] - 1; j++)  //Loop for number of non-zero elements in current row
                {
                    //result[i] += vector[col_ind[j] - 1] * val[j];
                    cell += vector[col_ind[j] - 1] * val[j];
                }
                //see above comment
                result[i] = cell;
            }
            );
        }

    }
}
